package com.why.simpleboot.core.server.netty.handler;

import com.why.simpleboot.core.core.entity.MethodDefinition;
import com.why.simpleboot.core.server.netty.resolver.ParameterResolver;
import com.why.simpleboot.core.server.netty.resolver.ParameterResolverFactory;
import com.why.simpleboot.core.server.netty.response.SimpleResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: why-simpleboot-framework
 * @description:
 * @author: @why
 * @create: 2021-05-22 14:32
 **/
public class GetRequestHandler extends AbstractRequestHandler {
    private Logger log = LoggerFactory.getLogger(GetRequestHandler.class);

    public GetRequestHandler() {

    }

    @Override
    public FullHttpResponse handle(FullHttpRequest httpRequest) {
        //如果返回的数据和当前对象相等 那就说明当前对象可以处理该请求
        RequestHandler handler = canProcessCurrentRequest(httpRequest, HttpMethod.GET);
        if (handler == null) {
            return SimpleResponse.createError(httpRequest.uri(), "无法处理该请求", HttpResponseStatus.NOT_FOUND);
        }
        if (!handler.equals(this)) {
            return handler.handle(httpRequest);
        }


        MethodDefinition methodDefinition = getMethodDefinition(httpRequest);
        if (methodDefinition == null) {
            return SimpleResponse.createError(httpRequest.uri(), "没有找到能够处理该请求的控制器", HttpResponseStatus.NOT_FOUND);
        }
//获取uri上附着的参数,并将其转换格式
        Map<String, String> parameters = getParameters(requestParamDecoder.parameters());

        methodDefinition.setRequestParameterMappings(parameters);

        List<Object> args = new ArrayList<>();
//        开始解析参数
        for (Parameter parameter : methodDefinition.getMethod().getParameters()) {
            ParameterResolver resolver = ParameterResolverFactory.getResolver(parameter);
            Object arg = resolver.resolve(methodDefinition, parameter);
            args.add(arg);
        }

        Object result = invokeMethodForTarget(methodDefinition, args.toArray());
        if (result == null&&methodDefinition.getMethod().getReturnType()==void.class) {
        return  SimpleResponse.createOk(null);
        }
        return SimpleResponse.createOk(result);
    }

    private Map<String, String> getParameters(Map<String, List<String>> parametersMap) {
        Map<String, String> map = new HashMap<>();

        parametersMap.forEach((key, value) -> {
            for (String data : value) {

                map.put(key, data);
            }

        });
        return map;
    }


}
